package lv.solcraft.replication.client;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.log4j.Logger;
import org.springframework.dao.DataAccessException;
import org.springframework.jdbc.core.support.JdbcDaoSupport;

/**
 * @author ilgvars
 */
public class OperLoaderSqlHolder extends JdbcDaoSupport {

    private static final Logger log = Logger.getLogger(OperLoaderSqlHolder.class);

    private static final String GET_TABLE_FIELDS_SQL = "SELECT RDB$FIELD_NAME FROM RDB$RELATION_FIELDS WHERE RDB$RELATION_NAME = ?";

    private static final String PROC_PARAMS_SQL = "SELECT RDB$PARAMETER_NAME" + " FROM RDB$PROCEDURE_PARAMETERS WHERE RDB$PROCEDURE_NAME = ?" + " AND RDB$PARAMETER_TYPE = 0"
            + " ORDER BY RDB$PARAMETER_NUMBER";

    private Map<String, LoadFieldsStatement> loadFieldsStatements;

    private ClientConfig clientConfig;

    public OperLoaderSqlHolder() {
        loadFieldsStatements = Collections.synchronizedMap(new HashMap<String, LoadFieldsStatement>());
    }

    public class LoadFieldsStatement {
        private String sql;

        private List<String> fields;

        public LoadFieldsStatement(String sql, List<String> fields) {
            this.sql = sql;
            this.fields = fields;
        }

        public List<String> getFields() {
            return fields;
        }

        public String getSql() {
            return sql;
        }

    }

    public LoadFieldsStatement getLoadFieldsStatement(String tableName) {
        LoadFieldsStatement st = loadFieldsStatements.get(tableName);
        if (st == null) {
            st = createLoadFieldsStatement(tableName);
            log.info("Creating fields load statement for table " + tableName + ": " + st.getSql());
            loadFieldsStatements.put(tableName, st);
        }
        return st;
    }

    private LoadFieldsStatement createLoadFieldsStatement(String tableName) throws DataAccessException {

        String sql = "";
        String fieldList = "";

        List fields = getJdbcTemplate().queryForList(GET_TABLE_FIELDS_SQL, new Object[] { tableName }, String.class);
        List<String> resultFields = new ArrayList<String>(fields.size());

        for (Object fieldName : fields) {
            String normalFieldName = fieldName.toString().trim().toUpperCase();
            // since 3.5.7, add only if field is not in ignore list
            if (!clientConfig.getSettings().isIgnoredField(tableName, normalFieldName)) {
                if (!fieldList.equals("")) {
                    fieldList = fieldList + ", ";
                }
                fieldList = fieldList + normalFieldName;
                resultFields.add(normalFieldName);
            }
        }

        sql = "SELECT " + fieldList + " FROM " + tableName + " WHERE SCR_SITE_ID = ? AND SCR_RECORD_ID = ?";

        return new LoadFieldsStatement(sql, resultFields);

    }

    public void setClientConfig(ClientConfig clientConfig) {
        this.clientConfig = clientConfig;
    }

}